use std::collections::VecDeque; //
use std::sync::atomic::{AtomicUsize, Ordering}; //
use std::sync::{Arc, Condvar, Mutex}; //
use std::thread; //

type Job = Box<dyn FnOnce() + Send + 'static>;

#[allow(dead_code)]
struct ThreadPollV1 {
    queue: Mutex<VecDeque<Job>>,
    idle_num: AtomicUsize,
    idle_worker: Condvar,
}

impl ThreadPollV1 {
    #[allow(dead_code)]
    pub fn new() -> Arc<ThreadPollV1> {
        Arc::new(ThreadPollV1 {
            queue: Mutex::new(VecDeque::new()),
            idle_worker: Condvar::new(),
            idle_num: AtomicUsize::new(0),
        })
    }

    #[allow(dead_code)]
    pub fn spawn<F>(self: Arc<Self>, f: F)
    where
        F: FnOnce() + Send + 'static,
    {
        let job = Box::new(f);

        {
            let mut queue = self.queue.lock().unwrap();
            queue.push_back(job);

            // 检查是否有空闲线程
            if self.idle_num.load(Ordering::Relaxed) == 0 {
                let pool = self.clone();
                thread::spawn(move || {
                    worker(pool);
                });
            } else {
                self.idle_worker.notify_one();
            }
        }
    }
}

fn worker(pool: Arc<ThreadPollV1>) {
    loop {
        let mut queue = pool.queue.lock().unwrap();
        match (&mut queue).pop_front() {
            Some(job) => {
                (job)();
            }
            None => {
                pool.idle_num.fetch_add(1, Ordering::AcqRel);
                let _queue = pool.idle_worker.wait(queue).unwrap(); // 这里释放锁并等待
                pool.idle_num.fetch_sub(1, Ordering::AcqRel);
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::sync::atomic::{AtomicUsize, Ordering};
    use std::sync::Arc;
    use std::time::Duration;

    #[test]
    fn test_thread_poll_creation() {
        let pool = ThreadPollV1::new();
        assert_eq!(pool.idle_num.load(Ordering::Relaxed), 0);
    }

    #[test]
    fn test_thread_poll_executes_single_job() {
        let pool = ThreadPollV1::new();
        let counter = Arc::new(AtomicUsize::new(0));

        let counter_clone = counter.clone();
        pool.spawn(move || {
            counter_clone.fetch_add(1, Ordering::SeqCst);
        });

        // 给线程一些时间执行
        std::thread::sleep(Duration::from_millis(100));

        assert_eq!(counter.load(Ordering::SeqCst), 1);
    }

    #[test]
    fn test_thread_poll_executes_multiple_jobs() {
        let pool = ThreadPollV1::new();
        let counter = Arc::new(AtomicUsize::new(0));

        for i in 0..5 {
            let pool_clone = pool.clone();
            let counter_clone = counter.clone();
            pool_clone.spawn(move || {
                counter_clone.fetch_add(1, Ordering::SeqCst);
                println!("Job {} executed", i);
            });
        }

        // 给线程足够时间执行所有任务
        std::thread::sleep(Duration::from_millis(500));

        assert_eq!(counter.load(Ordering::SeqCst), 5);
    }

    #[test]
    fn test_thread_poll_handles_concurrent_jobs() {
        let pool = ThreadPollV1::new();
        let counter = Arc::new(AtomicUsize::new(0));

        let mut handles = vec![];

        for _ in 0..3 {
            let pool_clone = pool.clone();
            let counter_clone = counter.clone();
            let handle = std::thread::spawn(move || {
                for _ in 0..10 {
                    let pool_inner = pool_clone.clone();
                    let counter_inner = counter_clone.clone();
                    pool_inner.spawn(move || {
                        counter_inner.fetch_add(1, Ordering::SeqCst);
                    });
                }
            });
            handles.push(handle);
        }

        for handle in handles {
            handle.join().unwrap();
        }

        // 给线程池时间处理所有任务
        std::thread::sleep(Duration::from_millis(1000));

        assert_eq!(counter.load(Ordering::SeqCst), 30);
    }

    #[test]
    fn test_thread_poll_idle_worker_management() {
        let pool = ThreadPollV1::new();

        // 初始状态应该是0个空闲线程
        assert_eq!(pool.idle_num.load(Ordering::Relaxed), 0);

        // 提交一个任务，应该创建一个工作线程
        let counter = Arc::new(AtomicUsize::new(0));
        let counter_clone = counter.clone();
        pool.clone().spawn(move || {
            counter_clone.fetch_add(1, Ordering::SeqCst);
        });

        // 给线程时间启动和执行
        std::thread::sleep(Duration::from_millis(100));

        // 任务完成后，应该有一个空闲线程
        // 注意：这个测试可能不稳定，因为线程状态变化很快
        std::thread::sleep(Duration::from_millis(50));
    }

    #[test]
    fn test_thread_poll_with_delayed_execution() {
        let pool = ThreadPollV1::new();
        let results = Arc::new(Mutex::new(Vec::new()));

        for i in 0..3 {
            let pool_clone = pool.clone();
            let results_clone = results.clone();
            pool_clone.spawn(move || {
                std::thread::sleep(Duration::from_millis(50 * (i + 1)));
                results_clone.lock().unwrap().push(i);
            });
        }

        // 等待所有任务完成，增加等待时间确保所有任务都能完成
        std::thread::sleep(Duration::from_millis(500));

        let results_vec = results.lock().unwrap();
        assert_eq!(
            results_vec.len(),
            3,
            "Expected 3 tasks to complete, but got {}",
            results_vec.len()
        );
        // 由于线程执行顺序不确定，我们只检查数量不检查顺序
    }
}
